#include "KRuntime.h"
#include "KTrace.h"
#include "KLinkArray.h"

namespace krt
{
	LinkArray::~LinkArray()
	{
		if (m_pNode) 
		{
			delete [] m_pNode;
			m_pNode = NULL;
		}
	}

	void LinkArray::init(size_t nSize)
	{
		if (m_pNode)
		{
			delete [] m_pNode;
			m_pNode = NULL;
			m_nCount = 0;
		}

		m_nCount = nSize;

		if (nSize)
			m_pNode = new LinkNode[nSize];
	}

	void LinkArray::remove(size_t nIdx)
	{
		if (!nIdx)
			return;

		if ((m_pNode[nIdx].GetNext() == 0 && m_pNode[0].GetPrev() != nIdx) || 
			(m_pNode[nIdx].GetPrev() == 0 && m_pNode[0].GetNext() != nIdx))
		{
			DbgOutput("[error]Node:%zd Remove twice", nIdx);
			return;
		}

		m_pNode[m_pNode[nIdx].GetPrev()].SetNext(m_pNode[nIdx].GetNext());
		m_pNode[m_pNode[nIdx].GetNext()].SetPrev(m_pNode[nIdx].GetPrev());
		m_pNode[nIdx].SetNext(0);
		m_pNode[nIdx].SetPrev(0);
		--m_nCount;
	}

	void LinkArray::insert(size_t nIdx)
	{
		if (!nIdx)
			return;

		if (m_pNode[nIdx].GetNext() || m_pNode[nIdx].GetPrev())
		{
			DbgOutput("[error]Node:%zd Insert twice", nIdx);
			return;
		}

		m_pNode[nIdx].SetNext(m_pNode[0].GetNext());
		m_pNode[m_pNode[0].GetNext()].SetPrev(nIdx);
		m_pNode[0].SetNext(nIdx);
		m_pNode[nIdx].SetPrev(0);
		++m_nCount;
	}
}
